/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package negocio;


import excepciones.SalaException;
import excepciones.UsuarioException;
import java.io.Serializable;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import controlador.CtrlPersistencia;
import javax.persistence.Column;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;



/**
 *
 * @author diego
 */
@Entity
public class Complejo implements Serializable {
    
    //Conoce a los Eventos
    @Id
    @Column(name="COMPLEJO_ID")
    private Integer id;
    
    @Basic
    private String nombre;
    
    @OneToMany
    @JoinColumn(name="COMPLEJO_ID", referencedColumnName="COMPLEJO_ID")
    private Set<Sala> salas;    
    
    @OneToMany
    @JoinColumn(name="COMPLEJO_ID", referencedColumnName="COMPLEJO_ID")
    private Set<Evento> eventos;
    
    @OneToMany
    @JoinColumn(name="COMPLEJO_ID", referencedColumnName="COMPLEJO_ID")
    private Map<String,Usuario> usuarios;
    
    @OneToMany
    @JoinColumn(name="COMPLEJO_ID", referencedColumnName="COMPLEJO_ID")
    private Set<TransaccionVentas> transaccionesVentas;
    
    @OneToMany
    @JoinColumn(name="COMPLEJO_ID", referencedColumnName="COMPLEJO_ID")
    private Set<Rol> roles;

    public Complejo() {
    }

    public Complejo(String nombre) {   
        this.nombre = nombre;
        this.salas = new HashSet();
        this.eventos = new HashSet();
        this.usuarios = new HashMap();
        this.transaccionesVentas = new HashSet(); 
        
        
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Set<Sala> getSalas() {
        Set<Sala> lista;
        lista = CtrlPersistencia.listaDeSalas();
        this.setSalas(lista);
        return lista;
    }
    public Set<Sala> getSalasActivas() {
        Set<Sala> lista;
        lista = CtrlPersistencia.listaDeSalasActivas();
        this.setSalas(lista);
        return lista;
    }

    public void setSalas(Set<Sala> salas) {
        this.salas = salas;        
    }

    public Set<Evento> getEventos() {
        
        Set<Evento> lista;
        lista = CtrlPersistencia.listaDeEventos();
        this.setEventos(lista);
        return lista;
    }

    public void setEventos(Set<Evento> eventos) {
        this.eventos = eventos;
    }

    public Map<String, Usuario> getUsuarios() {
        Map<String, Usuario> lista;
        lista = CtrlPersistencia.listaDeUsuarios();
        this.setUsuarios(lista);
        return lista;
    }

    public void setUsuarios(Map<String, Usuario> usuarios) {
        this.usuarios = usuarios;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public Set<TransaccionVentas> getTransaccionesVentas() {
        return transaccionesVentas;
    }

    public void setTransaccionesVentas(Set<TransaccionVentas> transaccionesVentas) {
        this.transaccionesVentas = transaccionesVentas;
    }

    public Set<Rol> getRoles() {
        return roles;
    }

    public void setRoles(Set<Rol> roles) {
        this.roles = roles;
    }    
    public void agregarEvento(Integer id, String nombre, String descripcion, boolean activo) throws Exception{
        Evento unEvento = new Evento(id,nombre,descripcion,activo);
        this.eventos.add(unEvento);
        CtrlPersistencia.crearEvento(unEvento);
        CtrlPersistencia.modificarComplejo(this);
    }
    
    public void agregarEvento(String nombre, String descripcion, boolean activo) throws Exception{
        Integer id = this.maxEvento();
        this.agregarEvento(id, nombre, descripcion, activo);
    }

    public void agregarUsuario (String unUserName,String unPassword,String unNivel,Rol unRol)throws UsuarioException, NoSuchAlgorithmException, Exception{
        Integer id = CtrlPersistencia.maxUsuarioId() + 1;
        this.agregarUsuario(id, unUserName, unPassword, unNivel,unRol);
    }
    public void agregarUsuario(Integer id,String unUserName,String unPassword,String unNivel,Rol unRol)throws UsuarioException, NoSuchAlgorithmException, Exception{
        this.recargarUsuarios(); //Fuerzo la carga de usuarios desde la db
        if(this.usuarios.containsKey(unUserName)){
            if(!this.usuarios.get(unUserName).isEstado()){
                this.usuarios.get(unUserName).activar();
            }else{
                throw new UsuarioException("Usuario Existente. Verifique");
            }
        }else{
            Usuario unUsuario = new Usuario(id,unUserName,unPassword,unNivel,unRol);
            this.usuarios.put(unUserName, unUsuario);
            CtrlPersistencia.crearUsuario(unUsuario);
            CtrlPersistencia.modificarComplejo(this);
        }        
    }
    
    public void recargarUsuarios(){        
        Map<String,Usuario> lista = new HashMap();
        lista = CtrlPersistencia.listaDeUsuarios();
        this.setUsuarios(lista);
    }
   
    public void quitarUsuario(String unUserName){
        if(this.usuarios.containsKey(unUserName)){
            this.usuarios.get(unUserName).desactivar();
        }
    }
    
    public Usuario validarUsuario(String unUserName,String unPassword) throws UsuarioException, NoSuchAlgorithmException{      
        
        //Busco el usuario
        Usuario unUsuario=null;
        
        if(this.getUsuarios().containsKey(unUserName)){
            unUsuario = this.getUsuarios().get(unUserName);
            if(!unUsuario.validarPass(unPassword)){
                unUsuario=null; 
            }
        }else{
            throw new UsuarioException("Usuario Inexistente",1);
        }
        return unUsuario;
    }
    
    /* Fin Metodos Usuario */
    
    public Set<Evento> obtenerEventos(){
        //Session sess = HibernateUtil.getSessionFactory().getCurrentSession();
       // Session sess = HibernateUtil.
        Set<Evento> varEventos = new HashSet();
        
        for (Evento unEvento : this.getEventos()) {
            if (unEvento.isActivo()){
                varEventos.add(unEvento);
            }
        }
        
        return varEventos;

    }
   /* 
    public Map<String,Butaca> obtenerButacas(Sala unaSala,Funcion unaFuncion){        
        
        return unaSala.obtenerButacas(unaFuncion);
    }
    */
    
    public boolean existeSala(String unNombreSala){
        boolean resultado = false;
        Iterator it = this.getSalas().iterator();
        while(!resultado && it.hasNext()){
            Sala unaSala = (Sala) it.next();
            if(unaSala.getNombre().equals(unNombreSala)){
                resultado = true;
            }
        }
        
        
        return resultado;
    }
    
    public void agregarSala(String unNombre, Integer capacidad,boolean estado) throws SalaException, Exception{
        if(this.existeSala(unNombre)){
            throw new SalaException("Sala Existente. Verifique");
        }else{
            Integer id = this.maxSala() + 1;
            Sala unaSala = new Sala(id,unNombre,capacidad,estado);
            this.salas.add(unaSala);
            //CtrlPersistencia.crearEmbarcacion(unaEmbarcacion);
            //CtrlPersistencia.modificarAgencia(this);
            CtrlPersistencia.crearSala(unaSala);
            CtrlPersistencia.modificarComplejo(this);
            
        }
        
    }
    public Integer maxSala(){
        return CtrlPersistencia.maxSalaID();
    }
    public Integer maxEvento(){
        return CtrlPersistencia.maxEventoID();
    }
    public Integer maxUsuario(){
        return CtrlPersistencia.maxUsuarioId();
    }
    public Integer maxTransaccionVentas(){
        return CtrlPersistencia.maxTransaccionVentasID();
    }
    
    public void guardarSala(String unNombre,Integer capacidad,boolean estado) throws SalaException, Exception{
        Iterator it = this.getSalas().iterator();
        boolean bandera = true;
        if(this.existeSala(unNombre)){
                //    Iterator it = this.getSalas().iterator();
            while(bandera && it.hasNext()){
                Sala unaSala = (Sala) it.next();
                if(unaSala.getNombre().equals(unNombre)){
                    unaSala.actualizar(unNombre,capacidad,estado);
                    bandera = false;
                    CtrlPersistencia.modificarComplejo(this);
                }
            }
        }
        
    }
    
    public void quitarSala(Sala unaSala){
       // unaSala.quitarSecciones();
        unaSala.deshabilitar();
    }
    
    
    
    
    public void agregarSeccionSala(Sala unaSala,String unCodigo) throws Exception{
        unaSala.agregarSeccion(unCodigo);
        
    }
    
    public Set<Sala> obtenerSalas(){
        Set<Sala> lista;
        lista = CtrlPersistencia.listaDeSalas();
        this.setSalas(lista);
        return lista;
    }
    
     public Complejo mostrarComplejo() throws Exception{
        Complejo auxComplejo = new Complejo();
        auxComplejo = CtrlPersistencia.mostrarComplejo();
        return auxComplejo;
    }

    
   
    
    
    
    
    

}
